package com.sdx.payment.wxpay;

import com.sdx.common.utils.HttpUtils;
import com.sdx.common.utils.Signature;
import com.sdx.common.utils.Utils;
import com.sdx.exception.SdxException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.dom4j.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;


/**
 * @ClassName WxpayAPI
 * @Description: 微信支付接口api
 * @author: tanbaocai
 * @date: 2018/9/28 10:02
 */
public class WxpayAPI {
	private static final Logger log = LoggerFactory.getLogger("wxpay");
	/**
	 * 获取node的值
	 *
	 * @param node
	 * @return 如果node是null，则返回null
	 */
	public static String getNodeStringValue(Node node) {
		if (node == null) {
			return null;
		} else {
			return node.getStringValue();
		}
	}

	private static Element xmlRequest(String url,XmlRequest xmlRequest,String key,String certPath) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, SdxException, IOException, DocumentException {
		String xmlContent = null;
		XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
		xStreamForRequestPostData.alias("xml", xmlRequest.getClass());
		//将要提交给API的数据对象转换成XML
		xmlContent = xStreamForRequestPostData.toXML(xmlRequest);
		String res = HttpUtils.httpsPost(url,xmlContent,key,certPath);
		Document doc = DocumentHelper.parseText(res);
		Element root = doc.getRootElement();
		return root;
	}
	/**
	 * 申请退款
	 * @param refundRequest
	 * @return
	 */
	public static RefundResponse refund(RefundRequest refundRequest,String key,String certPath) {
		String url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
		RefundResponse response = new RefundResponse();
		response.setSuccess(true);
		try {
			Element root = xmlRequest(url,refundRequest,key,certPath);
			parseResponse(root, response);
			if (response.isSuccess()) {
				//交易成功
				Node node = root.selectSingleNode("refund_fee");
				response.setRefundMoney(Integer.parseInt(node.getStringValue()));
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("refund[]",e);
			response.setSuccess(false);
			response.setErrCode("E4040");
			response.setMessage(e.getMessage());
		}
		return response;
	}

	/**
	 * 发红包
	 * @param sendRedPackRequest
	 * @param key
	 * @param storeKey
	 * @param certPath
	 * @return
	 * @throws IllegalAccessException
	 */
	public static String sendRedPack(SendRedPackRequest sendRedPackRequest,String key,String storeKey,String certPath) throws IllegalAccessException {
		String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
		sendRedPackRequest.setNonce_str(Utils.getRandomStringByLength(32));
		String sign = Signature.getSign(sendRedPackRequest,key);
		sendRedPackRequest.setSign(sign);
		try {
			Element root = xmlRequest(url,sendRedPackRequest,storeKey,certPath);
		} catch(Exception e) {
			e.printStackTrace();
			log.error("refund[]",e);
		}
		return null;

	}

	public static String transfers(TransferRequest transferRequest,String key,String storeKey,String certPath) throws IllegalAccessException {
		String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
		transferRequest.setNonce_str(Utils.getRandomStringByLength(32));
		String sign = Signature.getSign(transferRequest,key);
		transferRequest.setSign(sign);
		try {
			Element root = xmlRequest(url,transferRequest,storeKey,certPath);
		} catch(Exception e) {
			e.printStackTrace();
			log.error("refund[]",e);
		}
		return null;

	}

	public static void main(String[] args) throws IllegalAccessException, UnsupportedEncodingException, UnknownHostException {
		TransferRequest transferRequest = new TransferRequest();
		transferRequest.setMch_appid("wx48d6dad068b6924f");
		transferRequest.setMchid("1500588591");
		transferRequest.setPartner_trade_no("201905280932008");
		transferRequest.setOpenid("oRrN_4vTZRZ7n8SUccyuBWstv5-E");
		transferRequest.setCheck_name("NO_CHECK");
		transferRequest.setAmount(30);
		transferRequest.setDesc("高考助力");
		transferRequest.setSpbill_create_ip(Inet4Address.getLocalHost().getHostAddress());
		transfers(transferRequest,"5vym84qg66cl4a28wrpfcmlk5tr21y7i","1500588591","C:\\圣达信\\微信商户\\1500588591\\apiclient_cert.p12");
	}

	public static void main1(String[] args) throws IllegalAccessException {
		SendRedPackRequest sendRedPackRequest = new SendRedPackRequest();
		sendRedPackRequest.setMch_billno("201905280932002");
		sendRedPackRequest.setMch_id("1500588591");
		sendRedPackRequest.setWxappid("wxf9d68c74c9b41eb9");
		sendRedPackRequest.setSend_name("sdx");
		sendRedPackRequest.setRe_openid("oRrN_4vTZRZ7n8SUccyuBWstv5-E");
		sendRedPackRequest.setTotal_amount(100);
		sendRedPackRequest.setTotal_num(1);
		sendRedPackRequest.setWishing("gg");
		sendRedPackRequest.setClient_ip("192.168.31.181");
		sendRedPackRequest.setAct_name("kgzf");
		sendRedPackRequest.setRemark("gkzf1");
		sendRedPackRequest.setScene_id("PRODUCT_4");
		sendRedPack(sendRedPackRequest,"5vym84qg66cl4a28wrpfcmlk5tr21y7i","1500588591","C:\\圣达信\\微信商户\\1500588591\\apiclient_cert.p12");
	}
	/**
	 * 检查通信结果码和交易结果码
	 *
	 * @param root
	 * @param response ，如果通信结果码或交易结果码不成功，则返回false和错误信息
	 *                 可能还需要进一步的处理
	 */
	public static void parseResponse(Element root, Response response) {
		Node returnCode = root.selectSingleNode("return_code");
		Node node;
		if (!Response.CODE_SUCCESS.equalsIgnoreCase(returnCode.getStringValue())) {
			//通信失败
			response.setSuccess(false);
			Node returnMsg = root.selectSingleNode("return_msg");
			response.setMessage(getNodeStringValue(returnMsg));
		} else {
			//TODO 签字校验

			//通信成功
			Node resultCode = root.selectSingleNode("result_code");
			if (!Response.CODE_SUCCESS.equalsIgnoreCase(resultCode.getStringValue())) {
				//交易失败
				response.setSuccess(false);
				node = root.selectSingleNode("err_code");
				response.setErrCode(getNodeStringValue(node));
				node = root.selectSingleNode("err_code_des");
				response.setMessage(getNodeStringValue(node));
			}
		}
	}
}
